Use case: HASH process using SHA1 algorithm in DMA mode

Sequence diagram

HASH process

  @startuml
  participant "Application" as App
  participant "HASH" as HASH
  participant "NVIC" as nvic
  participant "DMA" as dma

  == HASH initialization and Configuration ==
  App -> HASH: HAL_HASH_Init()
  note right : Configure the data type
  App <-- HASH:\n\n\n\n
  ==   HASH process with SHA1 algorithm  ==
  group process: oneshot computing with single buffer
  App -> HASH: HAL_HASH_SHA1_Start_DMA()
  note right: compute HASH input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HASH_SHA1_Finish()
  note right: retrieve the computed digest \nreturned via a pointer

  end
  group process: computing with several input buffers
  App -> HASH: HAL_HASH_SHA1_Start_DMA()
  note right : write the first input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HASH_SHA1_Start_DMA()
  note right : write the last input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HASH_SHA1_Finish()
  note right: retrieve the computed digest \nreturned via a pointer
  end
  App <-- HASH:\n\n\n
  == HASH De-initialization  ==
  App -> HASH: HAL_HASH_DeInit()
  @enduml

HMAC process

  @startuml
  participant "Application" as App
  participant "HASH" as HASH
  participant "NVIC" as nvic
  participant "DMA" as dma

  == HASH initialization and Configuration ==
  App -> HASH: HAL_HASH_Init()
  note right : Configure the data type,\n key and key size
  App <-- HASH:\n\n\n\n
  ==  HASH process with SHA1 algorithm ==
  group process: oneshot computing with single buffer
  App -> HASH: HAL_HMAC_SHA1_Start_DMA()
  note right: compute HASH input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InCpltCallback()
  App -> HASH: HAL_HASH_SHA1_Finish()
  note right: retrieve the computed digest \nreturned via a pointer

  end
  group process: computing with several input buffers
  App -> HASH: HAL_HMACEx_SHA1_Step1_2_DMA()
  note right : write the first input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HMACEx_SHA1_Step2_DMA()
  note right : feed the next input buffer
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HMACEx_SHA1_Step2_3_DMA()
  note right : feed the last input buffer to \n the peripheral
  nvic -> dma: HAL_DMA_IRQ_Handler()
  dma -> HASH: DMA Transfer complete
  HASH -> App: HAL_HASH_InputCpltCallback()
  App -> HASH: HAL_HASH_SHA1_Finish()
  note right: retrieve the computed digest \nreturned via a pointer
  end
  == HASH De-initialization  ==
  App -> HASH: HAL_HASH_DeInit()

  @enduml

Code snippet

HAL1

HAL2

/* This example is used with HASH processing */

uint8_t Input[261] =
{0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
0x32,0x20,0x2a,0x2a,0x2a};
uint8_t Sha1output[20]={0};


/* HASH Initialization */
hhash.Instance = HASH;
hhash.Init.DataType = HASH_DATATYPE_8B;
HAL_HASH_Init(&hhash);
__HAL_HASH_SET_MDMAT();




/* Oneshot compute with single input buffer */
HAL_HASH_SHA1_Start_DMA(&hhash, Input, 261);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
HAL_HASH_SHA1_Finish(&hhash, Sha1output, 1);
while (HAL_HASH_GetState(&hhash) == HAL_HASH_STATE_BUSY);

/* Compute SHA1 with several inputs buffers */
HAL_HASH_SHA1_Start_DMA(&hhash, Input, 128);
while (HAL_HASH_GetState(&hhash) == HAL_HASH_STATE_BUSY);
HAL_HASH_SHA1_Start_DMA(&hhash, Input+192, 64);
while (HAL_HASH_GetState(&hhash) == HAL_HASH_STATE_BUSY);
HAL_HASH_SHA1_Start_DMA(&hhash, Input+256, 5);
__HAL_HASH_RESET_MDMAT();
HAL_HASH_SHA1_Finish(&hhash, Sha1output, 1);
while (HAL_HASH_GetState(&hhash) == HAL_HASH_STATE_BUSY);
/* De-initialization */
HAL_HASH_DeInit(&hhash);
/* This example is used with HASH processing */

uint8_t Input[261] =
{0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
0x32,0x20,0x2a,0x2a,0x2a};
uint8_t Sha1output[20]={0};
uint32_t sha1output_size;

/* HASH Initialization */
hhash.instance = HAL_HASH;
HAL_HASH_Init(&hhash, HAL_HASH);
HAL_HASH_SetInDMA(&hhash, &hdmaIn);
/* Configure SHA1 algorithm */
hash_cfg.data_swapping  = HAL_HASH_DATA_SWAP_BYTE;
hash_cfg.algorithm = HAL_HASH_ALGO_SHA1;
HAL_HASH_SetConfig(&hhash, &hash_cfg);

/* Oneshot compute with single input buffer */
HAL_HASH_Compute_DMA(&hhash, Input, 256, Sha1output, 20, &sha1output_size);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);



/* Compute SHA1 with several inputs buffers */
HAL_HASH_Update_DMA(&hhash, Input, 128);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
HAL_HASH_Update_DMA(&hhash, Input+192, 64);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
HAL_HASH_Update_DMA(&hhash, Input+256, 5);
/* Retrieve the computed digest */
HAL_HASH_Finish(&hhash, Sha1output, 20, &sha1output_size, 1);
while (HAL_HASH_GetState(&hhash) != HAL_HASH_STATE_IDLE);
/* De-initialization */
HAL_HASH_DeInit(&hhash);

Key changes

  1. HAL2 requires linking the DMA handle through a dedicated configuration function and uses unified DMA APIs.

  2. HAL2 uses unified input and digest completion callbacks for DMA transfers.